/* component */
import BaseSelectUser, { BaseSelectUserModeEnum } from '@src/component/common/BaseSelectUser/index.tsx'
import { ElTable } from 'element-ui/types/table'
/* enum */
import AuthEnum from '@model/enum/AuthEnum'
/* model */
import Role from '@model/entity/Role/Role'
import MsgModel from '@model/MsgModel'
import LoginUser from '@model/entity/LoginUser/LoginUser'
import { RoleAuthSaveModel } from '@model/param/in/Role'
/* vue */
import { computed, ComputedRef, nextTick } from 'vue'
/* hooks */
import { 
  useStoreBuyAndUseUserNumData, 
  useStoreFetchRoleAuthUpdate, 
  useStoreFetchRoleAutoAuth, 
  useStoreFetchRoleDelete, 
  useStoreFetchRoleReset, 
  useStoreFetchRoleTenantBuyAndUseUserNum, 
  useStoreRoleCurrentProduct, 
  useStoreTableSelection 
} from '@src/modules/account/role/store/hooks'
import { 
  useStoreCurrentSelectRole, 
  useStoreFetchAddUserList, 
  useStoreFetchRoleDeleteUser, 
  useStoreInitData, 
  useStoreRoles, 
  useStoreUserPage 
} from '@src/modules/account/role/store/hooks'
/* service */
import RoleService from '@service/RoleService'
/* util */
import { randomString, strConcat as concat } from 'pub-bbx-utils'
import Log from '@src/util/log'
import { isEmpty, isNotEmpty, isObject } from '@src/util/type'
import { confirm, message } from '@src/util/message'
/* service */
import UserService from '@service/UserService'
import TenantService from '@service/TenantService'
/* locales */
import {t as $t} from '@src/locales';

const SystemRoleGroupRole: Role = {
  id: randomString(),
  /* 预置角色 */
  name: $t('common.base.presetAdminRole')
}

const CustomRoleGroupRole: Role = {
  id: randomString(),
  /* 自定义角色 */
  name: $t('common.base.definedAdminRole')
}

export function useRoleViewTree() {
  
  const { systemRoles, customRoles } = useStoreRoles()
  
  const tree: ComputedRef<Role[]> = computed(() => {
    return [
      {
        ...SystemRoleGroupRole,
        disabledClick: true,
        disabledHover: true,
        children: systemRoles.value
      },
      {
        ...CustomRoleGroupRole,
        disabledClick: true,
        disabledHover: true,
        children: customRoles.value
      }
    ]
  })
  
  return {
    tree
  }
}

export function useRoleViewAuth() {
  
  const { auths, tenantType } = useStoreInitData()
  const { userList, isUserListEmpty } = useStoreUserPage()
  
  const isHaveAuthStaffAuth = computed(() => {
    
    // 独立端默认开启
    if (TenantService.isTenantTypeMultiClient(tenantType.value)) {
      return true
    }
    
    return RoleService.isHaveRoleAllAuth(auths.value[AuthEnum.AUTH_STAFF])
  })
  
  const isHaveRoleCreateAuth = computed(() => {
    return RoleService.isHaveRoleAllAuth(auths.value[AuthEnum.ROLE_CREATE])
  })
  
  const isHaveAccountViewAuth = computed(() => {
    return RoleService.isHaveRoleAllAuth(auths.value[AuthEnum.ACCOUNT_VIEW])
  })
  
  const isHaveRoleDeleteAuth = computed(() => {
    return RoleService.isHaveRoleAllAuth(auths.value[AuthEnum.ROLE_DELETE])
  })
  
  const canAddUser = computed(() => {
    return (
      isHaveAuthStaffAuth.value
      && isHaveRoleCreateAuth.value
    )
  })
  
  const canRemoveUser = computed(() => {
    return (
      isNotEmpty(userList.value)
      && isHaveAuthStaffAuth.value
      && isHaveRoleDeleteAuth.value
    )
  })
  
  const canBatchAllot = computed(() => {
    return isHaveAuthStaffAuth.value && !(isUserListEmpty.value)
  })
  
  const canEditRole = computed(() => {
    return RoleService.isHaveRoleAllAuth(auths.value[AuthEnum.ROLE_EDIT])
  })
  
  const canCreateRole = computed(() => {
    return isHaveRoleCreateAuth.value
  })
  
  const canDeleteRole = computed(() => {
    return isHaveRoleDeleteAuth.value
  })
  
  const canDefaultAllotUser = computed(() => {
    return (
      isHaveAuthStaffAuth.value
      && TenantService.isTenantTypeDingTalk(tenantType.value)
    )
  })
  
  const canViewUser = computed(() => {
    return isHaveAccountViewAuth.value
  })
  
  const canShowReportLink = computed(() => {
    return (
      RoleService.isHaveRolAuth(auths.value[AuthEnum.VIP_REPORT_VIEW])
      && RoleService.isHaveRolAuth(auths.value[AuthEnum.SYSTEM_SEETING])
    )
  })
  
  return {
    canAddUser,
    canBatchAllot,
    canRemoveUser,
    canEditRole,
    canCreateRole,
    canDeleteRole,
    canViewUser,
    canDefaultAllotUser,
    canShowReportLink
  }
}

export function useRoleView() {
  // 
}

export function useRoleViewAddUser() {
  
  const fetchAddUserList = useStoreFetchAddUserList()
  const { currentSelectRole } = useStoreCurrentSelectRole()
  
  const options = {
    title: $t('common.placeholder.selectMember_1') as string,
    max: -1,
    showNoDistribute: true,
    showServiceProvider: false,
    mode: BaseSelectUserModeEnum.Filter
  }
  
  function addUsers() {
    return (
      BaseSelectUser.props.multi.user(options)
        .then(result => {
          
          if (MsgModel.isSuccess(result)) {
            
            const users = result?.data?.users || []
            const params = {
              roleId: currentSelectRole.value.id,
              userIdList: concat(users.map(user => user.userId))
            }
            
            return fetchAddUserList(params)
            
          }
          
          return Promise.reject(result)
          
        })
        .catch(error => {
          Log.error(error, useRoleViewAddUser.name)
        })
    )
  }
  
  return addUsers
  
}

export function useRoleViewRoleDeleteUser() {
  
  const fetchRoleDeleteUser = useStoreFetchRoleDeleteUser()
  const { tableSelection } = useStoreTableSelection()
  const { currentSelectRole } = useStoreCurrentSelectRole()
  
  function roleBatchDeleteUser() {
    
    if (isEmpty(tableSelection.value)) {
      message.error($t('account.selectRemoveMember'))
      return
    }
    
    const hasSuperAdmin = tableSelection.value.some(user => UserService.isSuperAdmin(user))
    
    if (hasSuperAdmin) {
      message.error($t('account.removeAdminFailed'))
      return
    }
    
    return (
      confirm.warning($t('account.confirmRemoveSelectMember'))
        .then(() => {
          
          const params = {
            roleId: currentSelectRole.value.id,
            userIdList: concat(tableSelection.value.map(user => user.userId))
          }
          
          return fetchRoleDeleteUser(params)
          
        })
    )
  }
  
  function roleDeleteUser(user: LoginUser) {
    
    return (
      confirm.warning($t('account.confirmRemoveMember'))
        .then(() => {
          
          const params = {
            roleId: currentSelectRole.value.id,
            userIdList: concat([user.userId])
          }
          
          return fetchRoleDeleteUser(params)
          
        })
    )
    
  }
  
  return {
    roleDeleteUser,
    roleBatchDeleteUser
  }
}

export function useRoleViewRoleDeleteRole() {
  
  const fetchRoleDelete = useStoreFetchRoleDelete()
  
  function roleDelete() {
    
    return (
      confirm.warning($t('account.confirmDeleteMemberRole'))
        .then(() => {
          return fetchRoleDelete()
        })
    )
    
  }
  
  return roleDelete
}

export function useRoleViewRoleResetRole() {
  
  const fetchRoleReset = useStoreFetchRoleReset()
  
  function roleReset() {
    
    return (
      confirm.warning($t('account.confirmResetMemberRole'))
        .then(() => {
          return fetchRoleReset()
        })
    )
    
  }
  
  return roleReset
}

export function useRoleViewAllotRoles() {
  
  const fetchRoleDeleteUser = useStoreFetchRoleDeleteUser()
  const { tableSelection } = useStoreTableSelection()
  
  function roleDeleteUser() {
    
    if (isEmpty(tableSelection.value)) {
      message.error($t('account.selectMemberAllotRole'))
      return
    }
    
  }
  
  return roleDeleteUser
}

export function useRoleViewRoleAuthUpdate() {
  
  const fetchRoleAuthUpdate = useStoreFetchRoleAuthUpdate()
  
  function roleAuthUpdate(params: RoleAuthSaveModel) {
    return (
      fetchRoleAuthUpdate(params).then(result => {
        return result
      })
    )
  }
  
  return roleAuthUpdate
}

export function useRoleViewTableMatchSelected() {
  
  const { tableSelection, setTableSelection } = useStoreTableSelection()
  const { userList } = useStoreUserPage()
  
  function toggleSelection(rows: LoginUser[], tableRef: ElTable) {
    
    let isNotOnCurrentPage = false
    let row: LoginUser
    
    if (isNotEmpty(rows)) {
      
      for (let i = 0; i < rows.length; i++) {
        
        row = rows[i]
        
        isNotOnCurrentPage = userList.value.every(user => {
          return user.userId !== row.userId
        })
        
        if (isNotOnCurrentPage) return
      }
      
      userList.value.forEach(user => {
        tableRef.toggleRowSelection(user, false)
      })
      
      rows.forEach(row => {
        tableRef.toggleRowSelection(row, true)
      })
      
    } else {
      tableRef.clearSelection()
    }
    
  }
  
  function matchSelected(tableRef: ElTable) {
    
    const selected: LoginUser[] = userList.value.filter(user => {
      
      if (tableSelection.value.some(selection => selection.userId === user.userId)) {
        return user
      }
      
    })
    
    nextTick(() => {
      toggleSelection(selected, tableRef)
    })
    
  }
  
  return matchSelected
  
}

export function useRoleViewTenantBuyAndUseUserNum() {
  
  const fetchRoleTenantBuyAndUseUserNum = useStoreFetchRoleTenantBuyAndUseUserNum()
  const { buyAndUseUserNumData, setBuyAndUseUserNumData } = useStoreBuyAndUseUserNumData()
  const { currentProduct } = useStoreRoleCurrentProduct()
  
  function fetchRoleTenantBuyAndUseUserNumImpl() {
    
    const params = {
      productLine: currentProduct.value
    }
    
    fetchRoleTenantBuyAndUseUserNum(params).then(result => {
      
      if (MsgModel.isSuccess(result) && isObject(result?.data)) {
        setBuyAndUseUserNumData(result.data)
        return
      }
      
      if (MsgModel.isFail(result)) {
        message.error(result?.message || $t('account.getUsedFailed'))
      }
      
    })
    
  }
  
  return {
    buyAndUseUserNumData,
    fetchRoleTenantBuyAndUseUserNumImpl
  }
}

export function useRoleViewFetchAutoAuth() {
  
  const fetchRoleAutoAuth = useStoreFetchRoleAutoAuth()
  
  function fetchRoleAutoAuthImpl() {
    return (
      fetchRoleAutoAuth().then(result => {
        
        if (MsgModel.isSuccess(result) && isObject(result?.data)) {
          return result.data
        }
        
      })
    )
  }
  
  return fetchRoleAutoAuthImpl
}

export default {
  useRoleViewTree,
  useRoleViewRoleResetRole
}